{% extends "base.html" %}

{% block meta %}
    <meta name="menu-tag" content="22"/>
{% end block %}

{% block stylesheet %}
<link rel="stylesheet" type="text/css" href="{{static_url('css/bootstrap-markdown.min.css')}}">
<style type="text/css">
    #exp-container {
        margin: 0; 
        padding:0;
        overflow: hidden;
    }
</style>
{% end block %}

{% block main %}
<div style="height: 5px;"></div>

<div class="container" style="width: 100% !important">
    <!-- 左侧实验页面 -->
    <div class="col-md-8">
        <div id="exp-waiting">
            <div class="alert alert-info" id="exp-waiting-message">
                <p>实验环境准备中......</p>
            </div>
        </div>
        <div id="exp-container">
            <iframe width="100%" height="1000px" frameborder="0" scrolling="no" id="expframe"></iframe>
        </div>
    </div>
    <!-- 左侧可伸缩菜单栏结束 -->

    <!-- 右侧笔记页面 -->
    <div class="col-md-4">
        <ol class="breadcrumb">
            <li><a href="#"><strong id="coursename"></strong></a></li>
            <li><a href="#"><strong id="chaptername"></strong></a></li>
            <li class="active"><strong id="labname"></strong></li>
        </ol>
        <ul class="nav nav-tabs">
            <li class="active"><a href="#tab1" data-toggle="tab"><b>实验介绍</b></a></li>
            <li><a href="#tab2" data-toggle="tab"><b>实验文件</b></a></li>
        </ul>
        <div class="tab-content" style="min-height:500px">
            <div class="tab-pane active" id="tab1">
                <div class="panel panel-success">
                    <div class="panel-heading">
                        {% if showassignment %}
                        <b class="text text-danger">本实验需要提交实验作业</b>
                        {% end if %}
                    </div>
                    <div class="panel-body">
                        <form>
                            <div name="content" data-provider="markdown-preview" data-iconlibrary="fa" id="markdown_content"></div>
                        </form>
                    </div>
                    <div class="panel-footer">
                        {% if showassignment %}
                            <b class="text text-success" id="lblAssignment">本实验作业已提交</b>
                            <button type="button" class="btn btn-sm btn-success" id="btnAssignment">提交作业</button>
                        {% end if %}
                    </div>
                </div>
            </div>
            <div class="tab-pane" id="tab2">
                <div class="panel panel-primary" id="divStorages">
                    <div class="panel-heading">
                        当前路径：<b data-bind="text:current_path"></b>&nbsp;
                        <button class="btn btn-xs btn-info" title="返回上一级" data-bind="click:goParent, visible:current_path() != root_path">
                            <i class="fa fa-level-up"></i>
                        </button>
                    </div>
                    <div class="panel-body">
                        <table class="table table-striped">
                            <thead>
                                <tr>
                                    <th>名称</th>                                    
                                    <th>操作</th>
                                </tr>
                            </thead>
                            <tbody data-bind="foreach:storage_items">
                                <tr>
                                    <td>
                                        <b data-bind="text:name"></b>
                                        <button class="btn btn-xs btn-success" title="查看" data-bind="click:openFile, visible:viewerable()">
                                            <i class="fa fa-eye"></i>
                                        </button>
                                        <button class="btn btn-xs btn-info" title="进入" data-bind="click:$root.openDir, visible:isdir">
                                            <i class="fa fa-folder-open"></i>
                                        </button>
                                    </td>
                                    <td>
                                        <button class="btn btn-xs btn-warning" title="更名" data-bind="click:renameItem">
                                            <i class="fa fa-edit"></i>
                                        </button>
                                        <button class="btn btn-xs btn-danger" title="删除" data-bind="click:deleteItem">
                                            <i class="fa fa-remove"></i>
                                        </button>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                    <div class="panel-footer">
                        <button type="button" class="btn btn-sm  btn-primary" title="上传文件" data-bind="click:uploadFile">
                            <i class="fa fa-upload"></i>
                        </button>
                        <button type="button" class="btn btn-sm  btn-primary" title="新建文件夹" data-bind="click:newFolder">
                            <i class="fa fa-folder"></i>
                        </button>
                        <button type="button" class="btn btn-sm  btn-primary" title="下载完整实验包" data-bind="click:download">
                            <i class="fa fa-download"></i>
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- 文件浏览对话框开始 -->
<div id="dlgFileViewer" class="modal fade">
    <div class="modal-dialog">
        <div class="modal-content" style="width: 800px">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title" id="lblFilePath"></h4>
            </div>
            <div class="modal-body">
                <iframe width="100%" height="800px" frameborder="0" scrolling="no" style="margin:0; padding:0" id="fileviewerFrame"></iframe>
            </div>
        </div>
    </div>
</div>
<!-- 文件浏览对话框结束 -->

<!-- 更名对话框开始 -->
<div id="dlgRenameItem" class="modal fade">
    <div class="modal-dialog">
        <div class="modal-content" style="width: 800px">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title">更改文件/文件夹名称</h4>
            </div>
            <div class="modal-body">
                <form class="form-horizontal">
                    <div class="form-group">
                        <label class="control-label col-md-2">原名称：</label>
                        <div class="col-md-8">
                            <span class="form-control-static" id="dlgRenameItem_originItemName"/>
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="control-label col-md-2">新名称：</label>
                        <div class="col-md-6">
                            <input type="text" class="form-control" id="dlgRenameItem_newItemName"/>
                        </div>
                        <div class="col-md-2">
                            <span class="form-control-static" id="dlgRenameItem_extension"></span>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-offset-2 col-md-8">
                            <label class="text-danger form-control-static" id="dlgRenameItem_message"></label>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-offset-2">
                            <button type="button" class="btn btn-default" onclick="doRenameItem();">确定</button>
                            <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
<!-- 更名对话框结束 -->

<!-- 上传文件对话框开始 -->
<div id="dlgUploadFile" class="modal fade">
        <div class="modal-dialog">
            <div class="modal-content" style="width: 800px">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal">&times;</button>
                    <h4 class="modal-title">文件上传</h4>
                </div>
                <div class="modal-body">
                    <form class="form-horizontal">
                        <div class="form-group">
                            <label class="control-label col-md-2">选择文件：</label>
                            <div class="col-md-6">
                                <input type="file" class="form-control" id="dlgUploadFile_file"/>
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="col-md-offset-2 col-md-8">
                                <label class="text-danger form-control-static" id="dlgUploadFile_message"></label>
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="col-md-offset-2">
                                <button type="button" class="btn btn-default" onclick="doUploadFile();">确定</button>
                                <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
<!-- 上传文件对话框结束 -->

<!-- 新建目录对话框开始 -->
<div id="dlgNewFolder" class="modal fade">
    <div class="modal-dialog">
        <div class="modal-content" style="width: 800px">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title">新建文件夹</h4>
            </div>
            <div class="modal-body">
                <form class="form-horizontal">
                    <div class="form-group">
                        <label class="control-label col-md-2">文件夹名称：</label>
                        <div class="col-md-6">
                            <input type="text" class="form-control" id="dlgNewFolder_folderName"/>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-offset-2 col-md-8">
                            <label class="text-danger form-control-static" id="dlgNewFolder_message"></label>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-offset-2">
                            <button type="button" class="btn btn-default" onclick="doNewFolder();">确定</button>
                            <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
<!-- 新建目录对话框结束 -->
{% end block %}


{% block script %}
<script src="{{static_url('js/bootstrap-markdown.js') }}" type="text/javascript"></script>
<script src="{{static_url('js/bootstrap-markdown.zh.js') }}" type="text/javascript"></script>
<script src="{{static_url('js/markdown.js') }}"></script>
<script src="{{static_url('js/to-markdown.js') }}"></script>

<script type="text/javascript">
    var labCode = '{{code}}';               // 该实验对应的代码号
    var labFile = '{{labfile}}';            // 实验主文件名
    var serviceName = '';                   // 该实验对应的容器服务名称
    var allowedFileTypes = [];              // 记录允许用户上传的文件类型(后缀名)，同时也是允许在浏览器中查看的文件类型
    var labStorage = new LabStorage();      // 用于knockout绑定的数据源
    var load_interval_id = 0;
    var load_retry_counts = 0;              

    var showAssignment = false;
    {% if showassignment %}
        showAssignment = true;
    {% end if %}

    /***********************************************/
    /* knockout数据源定义开始                        */
    /***********************************************/
    function LabStorage(){
        var self = this;
        self.root_path = labCode;
        self.storage_items = ko.observableArray();
        self.current_path = ko.observable(self.root_path);

        self.goParent = function(){
            current = self.current_path();
            index = current.lastIndexOf('/');
            if (index == -1){
                return;
            }
            parent = current.substr(0, index);
            self.current_path(parent);
            list_lab_items();
        };

        self.openDir = function(){
            storage_item = this;
            self.current_path(storage_item.path());
            list_lab_items();
        };

        self.uploadFile = function(){
            $("#dlgUploadFile_file").val("");
            $("#dlgUploadFile_message").text("");
            $("#dlgUploadFile").modal({ 'backdrop': 'static' });
        };

        self.newFolder = function(){
            $("#dlgNewFolder_folderName").val("");
            $("#dlgNewFolder_message").text("");
            $("#dlgNewFolder").modal({ 'backdrop': 'static' });
        };

        self.download = function(){
            doDownload();
        };
    }

    function StorageItem(name, path, isdir){
        var self = this;
        self.name = ko.observable(name);
        self.path = ko.observable(path);
        self.isdir = ko.observable(isdir);

        self.viewerable = function(){
            var index = self.name().lastIndexOf('.');
            if (index == -1){
                return false;
            }
            ext = self.name().substr(index + 1);
            return (allowedFileTypes.indexOf(ext) == -1) ? false : true;
        }

        self.openFile = function(){
            var origin_url = $("#expframe").attr("src");
            var parent_path = origin_url.substr(0, origin_url.lastIndexOf('/'));
            parent_path = parent_path.replace('/notebooks/', '/edit/');
            var file_url = parent_path + '/' + this.name();
            $("#dlgFileViewer").modal({ 'backdrop': 'static' });
            $("#fileviewerFrame").attr("src", file_url);
            $("#lblFilePath").html(this.name())
        };

        self.deleteItem = function(){
            var itemName = this.name();
            doDeleteItem(itemName);
        };
        
        self.renameItem = function(){
            var extension = "";
            var extension_index = this.name().lastIndexOf('.');
            if (extension_index != -1){
                extension = this.name().substr(extension_index);
            }
            $("#dlgRenameItem_extension").text(extension);
            $("#dlgRenameItem_originItemName").text(this.name());
            $("#dlgRenameItem").modal({ 'backdrop': 'static' });
        }
    }
    /***********************************************/
    /* knockout数据源定义结束                        */
    /***********************************************/

    $(document).ready(function(){
        // (1) 准备实验界面
        prepare_lab();

        // (2) 实验指导文本窗格处理
        $.getJSON('/lab?operation=get_lab_guides&operand=' + labCode, function(jsonResult){
            var data = jsonResult.data;
            $("#coursename").html(data.coursename);
            $("#chaptername").html(data.chaptername);
            $("#labname").html(data.labname);

            //初始化编辑器
            $("#markdown_content").markdown({
                language: 'zh',
                hideable: true,
                onShow: function(e){
                    var text = data.guides;
                    text = text.replace(/\\n\\r/g, "\n\r");
                    e.setContent(text);
                }
            });
            $(document).click();                // 隐藏工具栏
        } );

        // (3) 检查作业提交状态
        if (showAssignment){
            $.getJSON('/lab_assignment?labcode=' + labCode, function(result){
                if (result){
                    $("#lblAssignment").show();
                    $("#btnAssignment").hide();
                } else{
                    $("#lblAssignment").hide();
                    $("#btnAssignment").show();
                    $("#btnAssignment").click(function(){
                        $.post('/lab_assignment?labcode=' + labCode, function(result2){
                            if (result2){
                                $("#lblAssignment").show();
                                $("#btnAssignment").hide();
                            } else{
                                bootbox.alert('提交作业出错');
                            }
                        });
                    });
                }
            });
        }

        // (4) 实验文件清单装载
        var requestData = {
            operation : 'allowed_file_types'
        };
        $.ajax({
            url: '/labstorage',
            type: "POST",
            data: JSON.stringify(requestData),
            dataType: 'JSON',
            success:function(jsonResult){
                allowedFileTypes = jsonResult.data;
                // 设定上传文件对话框支持的文件类型
                $("#dlgUploadFile_file").attr('accept', '.' + allowedFileTypes.join(',.'));
                // 装载文件清单并绑定
                list_lab_items();               
                ko.applyBindings(labStorage, document.getElementById("divStorages"));
            }
        });
    });

    // 实验准备
    function prepare_lab(){
        // (1) 确保实验文件目录就绪
        var divMsg = $("#exp-waiting-message");
        $("<p>正在准备实验目录文件......</p>").appendTo(divMsg);

        $.getJSON('/lab?operation=ensure_lab_files&operand=' + labCode, function(jsonResult1){
            if(jsonResult1.success){
                $("<p>实验目录文件准备完毕</p>").appendTo(divMsg);
                $("<p>正在准备容器运行环境......</p>").appendTo(divMsg);
                // 确保容器已经启动
                $.getJSON('/lab?operation=ensure_lab_container&operand=' + labCode, function(jsonResult2){
                    if(jsonResult2.success){
                        $("<p>容器环境准备完毕</p>").appendTo(divMsg);
                        $("<p>正在进入实验界面......</p>").appendTo(divMsg);
                        serviceName = jsonResult2.data;
                        load_jupyter_url();
                    } else{
                        $("<p class='text text-danger'>" + jsonResult2.message + "</p>").appendTo(divMsg);
                    }
                });
            } else{
                $("<p class='text text-danger'>" + jsonResult1.message + "</p>").appendTo(divMsg);
                return;
            }
        });
    }

    // 反复尝试装载jupyter notebook url
    function load_jupyter_url(){
        if (load_retry_counts >= 5){
            window.clearInterval(load_interval_id);
            $("<p class='text text-danger'>实验界面响应超时，请稍后重试刷新页面！</p>").appendTo($("#exp-waiting-message"));
            return;
        }
        $.getJSON('/lab?operation=check_notebook_ready&operand=' + serviceName, function(jsonResult){
            load_retry_counts++;
            if (jsonResult.data){
                window.clearInterval(load_interval_id);
                $("#exp-waiting").hide();
                $('#expframe').attr('src', jsonResult.data + '/' + labCode + '/' + labFile);
            } else{
                if (load_interval_id == 0){
                    load_interval_id = window.setInterval(load_jupyter_url, 5000);
                }
            }
        });
    }

    // 获取当前目录下所有文件和子目录
    function list_lab_items(){
        var requestData = {
            operation : 'list_items',
            path : labStorage.current_path()
        };

        $.ajax({
            url : '/labstorage', 
            type : 'POST', 
            dataType : 'JSON',
            data : JSON.stringify(requestData),
            success : function(jsonResult){
                if (!jsonResult.success){
                    console.log(jsonResult.message);
                } else{
                    var arr = [];
                    for(var i=0;i<jsonResult.data.length;i++){
                        item = jsonResult.data[i];
                        arr.push(new StorageItem(item.name, item.path, item.isdir))
                    }
                    labStorage.storage_items(arr);
                }
            }
        });
    }

    // 更新文件/目录名称
    function doRenameItem(){
        $("#dlgRenameItem_message").text("");

        var originItemName = $("#dlgRenameItem_originItemName").text();
        var newItemName = $("#dlgRenameItem_newItemName").val().trim();
        var extension = $("#dlgRenameItem_extension").text();
        
        if (!newItemName){
            $("#dlgRenameItem_message").text("新名称不能为空");
            return;
        }

        if (originItemName == newItemName + extension){
            $("#dlgRenameItem_message").text("原始名称和新名称不能相同");
            return;
        }

        var requestData = {
            operation : 'rename_item',
            path : labStorage.current_path(),
            operand : {
                originName : originItemName,
                newName : newItemName
            }
        };
        $.ajax({
            url : '/labstorage',
            type : 'POST', 
            dataType : 'JSON',
            data : JSON.stringify(requestData),
            success : function(jsonResult){
                if (!jsonResult.success){
                    $("#dlgRenameItem_message").text(jsonResult.message);
                } else{
                    $("#dlgRenameItem").modal('hide');
                    list_lab_items();
                }
            }
        });
    }

    // 上传新文件
    function doUploadFile(){
        $("#dlgUploadFile_message").text("");

        var ele = document.getElementById("dlgUploadFile_file")
        if (ele.files.length == 0){
            $("#dlgUploadFile_message").text("未选择文件")
            return;
        }

        var fileObj = ele.files[0];
        var form = new FormData();
        form.append("file", fileObj);
        
        $.ajax({
            url : '/labstorage_upload?path=' + labStorage.current_path(),
            type : "POST",
            data : form,
            dataType : 'JSON',
            processData : false,
            contentType : false,
            success : function(jsonResult){
                if(jsonResult.success){
                    list_lab_items()
                } else{
                    bootbox.alert(jsonResult.message);
                }
                $("#dlgUploadFile").modal('hide');
            }
        });
    }

    // 删除文件/目录
    function doDeleteItem(itemName){
        bootbox.confirm('确实要删除文件/文件夹 <b>' + itemName + '</b> 吗?', function(choice){
            if (choice){
                var requestData = {
                    operation : 'delete_item',
                    path : labStorage.current_path(),
                    operand : {
                        itemName : itemName
                    }
                };
                $.ajax({
                    url: '/labstorage',
                    type: "POST",
                    data: JSON.stringify(requestData),
                    dataType: 'JSON',
                    success:function(jsonResult){
                        if (!jsonResult.success){
                            bootbox.alert(message);
                        } else{
                            list_lab_items();
                        }
                    }
                });
            }
        });
    }

    // 新建文件夹
    function doNewFolder(){
        $("#dlgNewFolder_message").text("");

        var folderName = $("#dlgNewFolder_folderName").val().trim();
        
        if (!folderName){
            $("#dlgNewFolder_message").text("新名称不能为空");
            return;
        }

        var requestData = {
            operation : 'new_folder',
            path : labStorage.current_path(),
            operand : {
                folderName : folderName
            }
        };
        $.ajax({
            url : '/labstorage',
            type : 'POST', 
            dataType : 'JSON',
            data : JSON.stringify(requestData),
            success : function(jsonResult){
                if (!jsonResult.success){
                    $("#dlgNewFolder_message").text(jsonResult.message);
                } else{
                    $("#dlgNewFolder").modal('hide');
                    list_lab_items();
                }
            }
        });
    }

    // 打包下载实验文件
    function doDownload(){
        var path = window.location.search.substr(6);
        var url = '/labstorage_download';
        var form = $("<form></form>").attr("action", url).attr("method", "get");
        form.append($("<input></input>").attr("type", "hidden").attr("name", "path").attr("value", path));
        form.appendTo('body').submit().remove();
    }
            
</script>
{% end block %}
